/*
 * Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/
 * Dual-licensed under the BSD or MIT licenses
 */
(function (a, h, c, g) {
    var e = "ontouchstart" in c;
    var d = (function () {
        var j = c.createElement("div"), i = c.documentElement;
        if (!("pointerEvents" in j.style)) {
            return false
        }
        j.style.pointerEvents = "auto";
        j.style.pointerEvents = "x";
        i.appendChild(j);
        var k = h.getComputedStyle && h.getComputedStyle(j, "").pointerEvents === "auto";
        i.removeChild(j);
        return !!k
    })();
    var b = {
        listNodeName: "ol",
        itemNodeName: "li",
        rootClass: "dd",
        listClass: "dd-list",
        itemClass: "dd-item",
        dragClass: "dd-dragel",
        handleClass: "dd-handle",
        collapsedClass: "dd-collapsed",
        placeClass: "dd-placeholder",
        noDragClass: "dd-nodrag",
        emptyClass: "dd-empty",
        expandBtnHTML: '<button data-action="expand" type="button">Expand</button>',
        collapseBtnHTML: '<button data-action="collapse" type="button">Collapse</button>',
        group: 0,
        maxDepth: 5,
        threshold: 20
    };

    function f(i, j) {
        this.w = a(c);
        this.el = a(i);
        this.options = a.extend({}, b, j);
        this.init()
    }

    f.prototype = {
        init: function () {
            var i = this;
            i.reset();
            i.el.data("nestable-group", this.options.group);
            i.placeEl = a('<div class="' + i.options.placeClass + '"/>');
            a.each(this.el.find(i.options.itemNodeName), function (n, m) {
                i.setParent(a(m))
            });
            i.el.on("click", "button", function (n) {
                if (i.dragEl) {
                    return
                }
                var p = a(n.currentTarget), m = p.data("action"), o = p.parent(i.options.itemNodeName);
                if (m === "collapse") {
                    i.collapseItem(o)
                }
                if (m === "expand") {
                    i.expandItem(o)
                }
            });
            var l = function (m) {
                var n = a(m.target);
                if (!n.hasClass(i.options.handleClass)) {
                    if (n.closest("." + i.options.noDragClass).length) {
                        return
                    }
                    n = n.closest("." + i.options.handleClass)
                }
                if (!n.length || i.dragEl) {
                    return
                }
                i.isTouch = /^touch/.test(m.type);
                if (i.isTouch && m.touches.length !== 1) {
                    return
                }
                m.preventDefault();
                i.dragStart(m.touches ? m.touches[0] : m)
            };
            var k = function (m) {
                if (i.dragEl) {
                    m.preventDefault();
                    i.dragMove(m.touches ? m.touches[0] : m)
                }
            };
            var j = function (m) {
                if (i.dragEl) {
                    m.preventDefault();
                    i.dragStop(m.touches ? m.touches[0] : m)
                }
            };
            if (e) {
                i.el[0].addEventListener("touchstart", l, false);
                h.addEventListener("touchmove", k, false);
                h.addEventListener("touchend", j, false);
                h.addEventListener("touchcancel", j, false)
            }
            i.el.on("mousedown", l);
            i.w.on("mousemove", k);
            i.w.on("mouseup", j)
        }, serialize: function () {
            var i, j = 0, k = this;
            step = function (o, m) {
                var l = [], n = o.children(k.options.itemNodeName);
                n.each(function () {
                    var q = a(this), p = a.extend({}, q.data()), r = q.children(k.options.listNodeName);
                    if (r.length) {
                        p.children = step(r, m + 1)
                    }
                    l.push(p)
                });
                return l
            };
            i = step(k.el.find(k.options.listNodeName).first(), j);
            return i
        }, serialise: function () {
            return this.serialize()
        }, reset: function () {
            this.mouse = {
                offsetX: 0,
                offsetY: 0,
                startX: 0,
                startY: 0,
                lastX: 0,
                lastY: 0,
                nowX: 0,
                nowY: 0,
                distX: 0,
                distY: 0,
                dirAx: 0,
                dirX: 0,
                dirY: 0,
                lastDirX: 0,
                lastDirY: 0,
                distAxX: 0,
                distAxY: 0
            };
            this.isTouch = false;
            this.moving = false;
            this.dragEl = null;
            this.dragRootEl = null;
            this.dragDepth = 0;
            this.hasNewRoot = false;
            this.pointEl = null
        }, expandItem: function (i) {
            i.removeClass(this.options.collapsedClass);
            i.children('[data-action="expand"]').hide();
            i.children('[data-action="collapse"]').show();
            i.children(this.options.listNodeName).show()
        }, collapseItem: function (i) {
            var j = i.children(this.options.listNodeName);
            if (j.length) {
                i.addClass(this.options.collapsedClass);
                i.children('[data-action="collapse"]').hide();
                i.children('[data-action="expand"]').show();
                i.children(this.options.listNodeName).hide()
            }
        }, expandAll: function () {
            var i = this;
            i.el.find(i.options.itemNodeName).each(function () {
                i.expandItem(a(this))
            })
        }, collapseAll: function () {
            var i = this;
            i.el.find(i.options.itemNodeName).each(function () {
                i.collapseItem(a(this))
            })
        }, setParent: function (i) {
            if (i.children(this.options.listNodeName).length) {
                i.prepend(a(this.options.expandBtnHTML));
                i.prepend(a(this.options.collapseBtnHTML))
            }
            i.children('[data-action="expand"]').hide()
        }, unsetParent: function (i) {
            i.removeClass(this.options.collapsedClass);
            i.children("[data-action]").remove();
            i.children(this.options.listNodeName).remove()
        }, dragStart: function (l) {
            var o = this.mouse, p = a(l.target), k = p.closest(this.options.itemNodeName);
            this.placeEl.css("height", k.height());
            o.offsetX = l.offsetX !== g ? l.offsetX : l.pageX - p.offset().left;
            o.offsetY = l.offsetY !== g ? l.offsetY : l.pageY - p.offset().top;
            o.startX = o.lastX = l.pageX;
            o.startY = o.lastY = l.pageY;
            this.dragRootEl = this.el;
            this.dragEl = a(c.createElement(this.options.listNodeName)).addClass(this.options.listClass + " " + this.options.dragClass);
            this.dragEl.css("width", k.width());
            k.after(this.placeEl);
            k[0].parentNode.removeChild(k[0]);
            k.appendTo(this.dragEl);
            a(c.body).append(this.dragEl);
            this.dragEl.css({left: l.pageX - o.offsetX, top: l.pageY - o.offsetY});
            var m, j, n = this.dragEl.find(this.options.itemNodeName);
            for (m = 0; m < n.length; m++) {
                j = a(n[m]).parents(this.options.listNodeName).length;
                if (j > this.dragDepth) {
                    this.dragDepth = j
                }
            }
        }, dragStop: function (i) {
            var j = this.dragEl.children(this.options.itemNodeName).first();
            j[0].parentNode.removeChild(j[0]);
            this.placeEl.replaceWith(j);
            this.dragEl.remove();
            this.el.trigger("change");
            if (this.hasNewRoot) {
                this.dragRootEl.trigger("change")
            }
            this.reset()
        }, dragMove: function (k) {
            var n, s, u, q, j, r = this.options, o = this.mouse;
            this.dragEl.css({left: k.pageX - o.offsetX, top: k.pageY - o.offsetY});
            o.lastX = o.nowX;
            o.lastY = o.nowY;
            o.nowX = k.pageX;
            o.nowY = k.pageY;
            o.distX = o.nowX - o.lastX;
            o.distY = o.nowY - o.lastY;
            o.lastDirX = o.dirX;
            o.lastDirY = o.dirY;
            o.dirX = o.distX === 0 ? 0 : o.distX > 0 ? 1 : -1;
            o.dirY = o.distY === 0 ? 0 : o.distY > 0 ? 1 : -1;
            var p = Math.abs(o.distX) > Math.abs(o.distY) ? 1 : 0;
            if (!o.moving) {
                o.dirAx = p;
                o.moving = true;
                return
            }
            if (o.dirAx !== p) {
                o.distAxX = 0;
                o.distAxY = 0
            } else {
                o.distAxX += Math.abs(o.distX);
                if (o.dirX !== 0 && o.dirX !== o.lastDirX) {
                    o.distAxX = 0
                }
                o.distAxY += Math.abs(o.distY);
                if (o.dirY !== 0 && o.dirY !== o.lastDirY) {
                    o.distAxY = 0
                }
            }
            o.dirAx = p;
            if (o.dirAx && o.distAxX >= r.threshold) {
                o.distAxX = 0;
                u = this.placeEl.prev(r.itemNodeName);
                if (o.distX > 0 && u.length && !u.hasClass(r.collapsedClass)) {
                    n = u.find(r.listNodeName).last();
                    j = this.placeEl.parents(r.listNodeName).length;
                    if (j + this.dragDepth <= r.maxDepth) {
                        if (!n.length) {
                            n = a("<" + r.listNodeName + "/>").addClass(r.listClass);
                            n.append(this.placeEl);
                            u.append(n);
                            this.setParent(u)
                        } else {
                            n = u.children(r.listNodeName).last();
                            n.append(this.placeEl)
                        }
                    }
                }
                if (o.distX < 0) {
                    q = this.placeEl.next(r.itemNodeName);
                    if (!q.length) {
                        s = this.placeEl.parent();
                        this.placeEl.closest(r.itemNodeName).after(this.placeEl);
                        if (!s.children().length) {
                            this.unsetParent(s.parent())
                        }
                    }
                }
            }
            var l = false;
            if (!d) {
                this.dragEl[0].style.visibility = "hidden"
            }
            this.pointEl = a(c.elementFromPoint(k.pageX - c.body.scrollLeft, k.pageY - (h.pageYOffset || c.documentElement.scrollTop)));
            if (!d) {
                this.dragEl[0].style.visibility = "visible"
            }
            if (this.pointEl.hasClass(r.handleClass)) {
                this.pointEl = this.pointEl.parent(r.itemNodeName)
            }
            if (this.pointEl.hasClass(r.emptyClass)) {
                l = true
            } else {
                if (!this.pointEl.length || !this.pointEl.hasClass(r.itemClass)) {
                    return
                }
            }
            var t = this.pointEl.closest("." + r.rootClass),
                m = this.dragRootEl.data("nestable-id") !== t.data("nestable-id");
            if (!o.dirAx || m || l) {
                if (m && r.group !== t.data("nestable-group")) {
                    return
                }
                j = this.dragDepth - 1 + this.pointEl.parents(r.listNodeName).length;
                if (j > r.maxDepth) {
                    return
                }
                var i = k.pageY < (this.pointEl.offset().top + this.pointEl.height() / 2);
                s = this.placeEl.parent();
                if (l) {
                    n = a(c.createElement(r.listNodeName)).addClass(r.listClass);
                    n.append(this.placeEl);
                    this.pointEl.replaceWith(n)
                } else {
                    if (i) {
                        this.pointEl.before(this.placeEl)
                    } else {
                        this.pointEl.after(this.placeEl)
                    }
                }
                if (!s.children().length) {
                    this.unsetParent(s.parent())
                }
                if (!this.dragRootEl.find(r.itemNodeName).length) {
                    this.dragRootEl.append('<div class="' + r.emptyClass + '"/>')
                }
                if (m) {
                    this.dragRootEl = t;
                    this.hasNewRoot = this.el[0] !== this.dragRootEl[0]
                }
            }
        }
    };
    a.fn.nestable = function (j) {
        var i = this, k = this;
        i.each(function () {
            var l = a(this).data("nestable");
            if (!l) {
                a(this).data("nestable", new f(this, j));
                a(this).data("nestable-id", new Date().getTime())
            } else {
                if (typeof j === "string" && typeof l[j] === "function") {
                    k = l[j]()
                }
            }
        });
        return k || i
    }
})(window.jQuery || window.Zepto, window, document);